From f31cbebeda7e5be846d087f9433c0aa19926a2c5 Mon Sep 17 00:00:00 2001 From: "arun.sharma@intel.com[iap10]" Date: Fri, 25 Feb 2005 00:49:46 +0000 Subject: [PATCH] bitkeeper revision 1.1236.1.19 (421e762a-grjFXfk-0fR1nd4ASovMA) [PATCH] Support 1000 HZ guests - Support guests with 1000 Hz - cleanup the trailing garbage in vmx_virtpit.h - Don't queue up pending timer interrupts before the first interrupt is injected - This fixes the low bogomips problem - Protect xen against guests programming a bad value for the counter Signed-off-by: Edwin Zhai Signed-off-by: Arun Sharma --- xen/arch/x86/vmx_intercept.c | 17 +++++++++---- xen/arch/x86/vmx_io.c | 6 +++++ xen/include/asm-x86/vmx_virpit.h | 41 +------------------------------- xen/include/xen/lib.h | 2 ++ 4 files changed, 22 insertions(+), 44 deletions(-) diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index 8427ffb1a3..d9299d5c22 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -203,7 +203,7 @@ static void pit_timer_fn(unsigned long data) /* Only some PIT operations such as load init counter need a hypervisor hook. - * leave many other operations in user space DM + * leave all other operations in user space DM */ void vmx_hooks_assist(struct exec_domain *d) { @@ -213,11 +213,20 @@ void vmx_hooks_assist(struct exec_domain *d) struct vmx_virpit_t *vpit = &(d->arch.arch_vmx.vmx_platform.vmx_pit); int rw_mode; - if (p->state == STATE_IORESP_HOOK) { /*load init count*/ - vpit->init_val = (p->u.data & 0xFFFF) ; /* frequency(ms) of pit */ - vpit->period = (vpit->init_val) * 1000 / PIT_FREQ; /* frequency(ms) of pit */ + /* load init count*/ + if (p->state == STATE_IORESP_HOOK) { + /* init count for this channel */ + vpit->init_val = (p->u.data & 0xFFFF) ; + /* frequency(ms) of pit */ + vpit->period = DIV_ROUND(((vpit->init_val) * 1000), PIT_FREQ); + if (vpit->period < 1) { + printk("VMX_PIT: guest programmed too small an init_val: %lx\n", + vpit->init_val); + vpit->period = 1; + } vpit->vector = ((p->u.data >> 16) & 0xFF); vpit->channel = ((p->u.data >> 24) & 0x3); + vpit->first_injected = 0; vpit->count_LSB_latched = 0; vpit->count_MSB_latched = 0; diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index d4a427a7f8..fcfe2ff36a 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -367,6 +367,12 @@ void vmx_intr_assist(struct exec_domain *d) else clear_highest_bit(d, highest_vector); + /* close the window between guest PIT initialization and sti */ + if (highest_vector == vpit->vector && !vpit->first_injected){ + vpit->first_injected = 1; + vpit->pending_intr_nr = 0; + } + intr_fields = (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR | highest_vector); __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields); diff --git a/xen/include/asm-x86/vmx_virpit.h b/xen/include/asm-x86/vmx_virpit.h index 91a08c204d..35fe69c844 100644 --- a/xen/include/asm-x86/vmx_virpit.h +++ b/xen/include/asm-x86/vmx_virpit.h @@ -1,4 +1,3 @@ - #ifndef _VMX_VIRPIT_H #define _VMX_VIRPIT_H #include @@ -25,6 +24,7 @@ struct vmx_virpit_t { unsigned int pending_intr_nr; /* the couner for pending timer interrupts */ unsigned long long inject_point; /* the time inject virt intr */ struct ac_timer pit_timer; /* periodic timer for mode 2*/ + int first_injected; /* flag to prevent shadow window */ /* virtual PIT state for handle related I/O */ int read_state; @@ -40,42 +40,3 @@ struct vmx_virpit_t { extern void vmx_hooks_assist(struct exec_domain *d); #endif /* _VMX_VIRPIT_H_ */ - -#ifndef _VMX_VIRPIT_H -#define _VMX_VIRPIT_H -#include -#include -#include -#include -#include -#include -#include - -#define PIT_FREQ 1193181 - -#define LSByte 0 -#define MSByte 1 -#define LSByte_multiple 2 -#define MSByte_multiple 3 - -struct vmx_virpit_t { - /* for simulation of counter 0 in mode 2*/ - int vector; /* the pit irq vector */ - unsigned int period; /* the frequency. e.g. 10ms*/ - unsigned int channel; /* the pit channel, counter 0~2 */ - unsigned long *intr_bitmap; - unsigned int pending_intr_nr; /* the couner for pending timer interrupts */ - unsigned long long inject_point; /* the time inject virt intr */ - struct ac_timer pit_timer; /* periodic timer for mode 2*/ - - /* virtual PIT state for handle related I/O */ - int read_state; - int count_LSB_latched; - int count_MSB_latched; - - unsigned int count; /* the 16 bit channel count */ - unsigned int init_val; /* the init value for the counter */ - -} ; - -#endif /* _VMX_VIRPIT_H_ */ diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index fb0e52c448..fb809de82a 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -23,6 +23,8 @@ #define SWAP(_a, _b) \ do { typeof(_a) _t = (_a); (_a) = (_b); (_b) = _t; } while ( 0 ) +#define DIV_ROUND(x, y) (((x) + (y) - 1) / (y)) + #define reserve_bootmem(_p,_l) ((void)0) struct domain; -- 2.30.2